home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Netware Super Library
/
Netware Super Library.iso
/
pgm_tool
/
lu62
/
int68.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-07-03
|
33KB
|
1,205 lines
/*
* This file contains some functionally close enough subroutines which
* have deal with initial and ending phases of the LU 6.2 verb processing.
*
* The "rout" subroutine represents the main entry point of the APPC
* (Advanced Program to Program Communication or in other words LU 6.2)
* module. This is in fact the first subroutine which has deal with
* processing of APPC requests.
* The APPC requests may come from two sources:
* - from application program via int 68h, or from
* - remote APPC module via network.
*
* CopyRight 1995. Nicholas Poljakov all rights reserved.
*
*/
#include <dos.h>
#include <malloc.h>
#include <stdlib.h>
#include <rcb.h>
#include <common.h>
#include <attlu.h>
#include <detach.h>
#include <tcb.h>
#include <scb.h>
#include <rpl.h>
#include <nib.h>
#include <mode.h>
#include <tps.h>
#include <partner.h>
#include <repass.h>
#include <stdio.h>
#include <include.h>
#include <string.h>
#include <fcntl.h> /* @0100 */
#include <process.h>
#include <arcb.h>
#include <rcballoc.h>
#include <crtp.h>
#include <state1.h>
#include <sys\types.h>
#include <sys\stat.h>
int sk_r_wt(void *);
int SendBlock(void *, void *);
int setrc(void *, void *);
int sendhsf(void *);
int sendhs(void *);
int sendbm(void *, void *);
int sendat(void *);
int rtsend(void *);
unsigned long rmfmh5(void *, void *);
int recwait(void *);
int rcvru(void *, void *);
int rcvhs(void *, void *, void *, void *);
int ralloc(void *, void *);
int psrm(int, void *, void *);
int ps_conv(int, void *);
int proterr(void *, unsigned long);
int preptrcv(void *, void *);
int post_rcb(void *);
struct repass *postopen(void *);
int phsrec(void *);
int pfmh5(void *);
int opndst(void *);
int obtsess(void *, unsigned char);
int Lrf_handler(void *);
int get_sess(void *, void *);
int get_attr(void *);
int fsm_error(unsigned char, void *);
int fsm_conv(unsigned char, unsigned char, void *);
int flush (void *);
int dcp(void *);
int dealloc(void *);
int crtp(void *);
int conv(void *);
int chkparm(void *, void *);
int check_end(unsigned int, void *);
int close_acb(void *);
struct rqb *call_appl(void *);
int buffmng(unsigned char, void *, void *, void *, unsigned, unsigned char, unsigned);
unsigned long attltck(void *);
unsigned long attacheck(void *);
int lu_init(void *);
int lu_sdown(void *);
int clt_vb(unsigned int, void *);
int sessi(unsigned int, void *);
int sessd(unsigned int, void *);
int fpost(void *);
int seek_res(void *);
char *cgetmem(int, int);
int sendhsf(void *);
int opndst(void *);
int alloc_rcb(void *, void *);
int allocate(void *);
int clsdst(void *);
unsigned long calltpn(void *, void *);
extern unsigned ProgPrefix;
struct psp {
struct lucb *lucb_list_ptr; /* π¬áºáΓѽ∞ ¡á ß»¿ß«¬ lucb */
struct tcb *tcb_list_ptr ; /* π¬áºáΓѽ∞ ¡á ß»¿ß«¬ tcb */
struct rcb *rcb_list_ptr ; /* π¬áºáΓѽ∞ ¡á ß»¿ß«¬ rcb */
struct rcb *wait_chain; /* «τÑpÑñ∞ «ª¿ñáεΘ¿σ RCB */
char *param;
} psp_ini = {NULL, NULL, NULL, NULL, NULL};
struct lucb {
char lu_id[8]; /* ¿ñÑ¡Γ¿Σ¿¬áΓ«α ½«¬á½∞¡«ú« LU */
unsigned char rsrv1;
char lu_name[8]; /* ¿¼∩ LU */
unsigned char rsrv2;
struct acb *p_acb;
struct pnlu *pluptr; /* π¬áºáΓѽ∞ ¡á
* ᯨ᮪ partner_lu */
struct trp *trp_ptr; /* π¬áºáΓѽ∞ ¡á
* transaction_program_list */
struct pending_data_list *pdlptr; /* ß»¿ß«¬ ñá¡¡δσ,
* »«ß½á¡¡δσ ó BIND
* ¬ »áαΓ¡Ñαπ */
struct mode *p_mode; /* List of mode blocks for this LU */
struct scb *scb_list;
unsigned char lu_session_limit; /* ¼á¬ß¿¼á½∞¡«Ñ ¬«½¿τÑßΓó«
ßÑßß¿⌐ LU-LU ñ½∩ ½«¬á½∞¡«ú« LU */
unsigned char cur_sess; /* current number of sessions*/
int max_tps; /* max. number of total tps for this LU */
int cur_tps; /* current number of tps */
int queue_depth;
struct tcb *tcb_list_ptr ; /* π¬áºáΓѽ∞ ¡á ß»¿ß«¬ tcb */
struct lucb *next; /* next LUCB */
} lu6;
struct acb {
short rsrv1;
short leng;
char rsrv2[4];
unsigned long int iface;
char rsrv3;
unsigned macr2:8;
struct acb *acb_next;
struct rpl *rpl;
char rsrv4[10];
unsigned long int passw;
unsigned long int uel;
char rsrv5[3];
unsigned am:8; /* 0x60-NTAM */
unsigned long int deb;
unsigned oflgs:8; /* 0x10-OPEN */
unsigned erflg:8; /* 0x04-ALREADY OPEN *
* 0x14-NOT ENOUGH STORAGE*/
char rsrv6[22];
unsigned long int apid;
char rtn[6];
} acb_ini;
int sw_retry[10];
char dispflag;
struct rcb *wait_rcb;
extern void (_interrupt _far *oldint68)( void );
extern char svarea;
extern char _huge *tsrstack;
char _huge *altstack;
char _huge *altsave;
extern char lupost;
void _far *tp_exit;
char *buff;
/* Literal pool */
char name_lu6[8] = "LU6****";
/* char name6[8] = "MODE6**";
char name0[8] = "MODE0**";
char name_tp[8] = "TP00001"; */
char tpi[6] = "TPXXX";
unsigned int code; /* Verb code */
unsigned int SaveCode[10];
unsigned int mask;
char *s_ptr; /* Pointer to verb record */
char *SavePtr[10];
char *t_ptr;
int from_appl[10];
int ss_ptr = 0;
char *temp;
struct in_parm {
unsigned int verb_cd;
unsigned long verb_ptr;
} parm;
struct repass *p_rep;
struct rqb *p_rqb;
#define HSrec 0x00ff
void _interrupt _far rout( unsigned _es, unsigned _ds, unsigned _di,
unsigned _si, unsigned _bp, unsigned _sp,
unsigned _bx, unsigned _dx, unsigned _cx,
unsigned _ax, unsigned _ip, unsigned _cs,
unsigned _flags )
{
/*
* Map of svarea -
* offset : 0 - sp of application programm
* offset : 2 - ss of application programm
* offset : 4 - sp of "appl" part of PORT
* offset : 6 - ss of "appl" part of PORT
* offset : 8 - ds of LU module.
* offset : 20 - pointer to psp_ini
*/
/* Save current stack of application, and set old stack of TSR.
* This is for safety since we don't know the state of the
* application stack, but we do know the state of our own stack.
* Turn off interrupts during the stack switch.
*/
FP_SEG( s_ptr ) = _ds;
FP_OFF( s_ptr ) = _dx;
_disable();
code = _ax;
SaveCode[ss_ptr] = code; /* Save code for retry */
SavePtr[ss_ptr] = s_ptr;
_asm
{
mov ax, seg svarea
push es
mov es, ax
mov ax, ds
mov WORD PTR es:svarea[8], ax ; Save data segment
pop es
}
mask = code & 0x00ff;
if (mask == 0x00ff) { /* from APPL */
from_appl[ss_ptr] = YES;
p_rqb = (struct rqb *)s_ptr;
if (!(p_rqb ->th.ra.code & 0x7f)) {
/* Segment */
s_ptr -= 12;
}
_asm
{
mov ax, seg svarea
mov es, ax
mov WORD PTR es:svarea[4], sp ; Save current stack
mov WORD PTR es:svarea[6], ss
mov ax, seg altstack
mov es, ax
mov sp, WORD PTR es:altstack[0] ; Load LU stack
mov ss, WORD PTR es:altstack[2]
}
}
else
{
from_appl[ss_ptr] = No;
_asm
{
mov ax, seg svarea
mov es, ax
mov WORD PTR es:svarea[0], sp ; Save current stack
mov WORD PTR es:svarea[2], ss
mov ax, seg tsrstack
mov es, ax
mov sp, WORD PTR es:tsrstack[0] ; Load LU stack
mov ss, WORD PTR es:tsrstack[2]
}
}
ss_ptr++;
_enable();
/* Make APPC verb processing */
/*
* Init. verb record if request from TP.
*/
if ((code != POSTOPEN)&&(code != DR)&&
(code != FMHRCV)&&(code != SESSINI)&&
(code != CLSSESS)&&(code != CLSSESS)) {
p_rep = (struct repass *)s_ptr;
p_rep -> complete = 0;
p_rep -> p_rcb = NULL;
p_rep -> tp_fd = 0;
}
Retry :
switch (code) {
case LRF : { /* Local resource failure */
Lrf_handler(s_ptr);
break;
}
case Attach_lu:
{
lu_init(s_ptr);
break;
}
case Detach_lu:
{
lu_sdown(s_ptr);
break;
}
case TP_STARTED:
case TP_ENDED:
{
clt_vb(code, s_ptr);
break;
}
case FMHRCV : /* Record from HS, FMH-5 or FMH-7 header */
{
/* s_ptr points to RQB */
s_ptr = (char *)s_ptr - 12;
/* s_ptr points to SEGPRF now */
phsrec(s_ptr);
break;
}
case SESSINI :
{
/* s_ptr points to RQB */
s_ptr = (char *)s_ptr - 12;
/* s_ptr points to SEGPRF now */
sessi(code, s_ptr);
break;
}
case CLSSESP :
case CLSSESS :
{
sessd(code, s_ptr);
break;
}
case DR :
{
if (fpost(s_ptr) == 0) {
}
break;
}
case CONVERT :
{
conv(s_ptr);
break;
}
case POSTOPEN:
{
t_ptr = (char *)postopen(s_ptr);
temp = t_ptr;
if (temp == NULL) {
code = -1;
}
break;
}
case Allocate:
{
ps_conv(code,s_ptr);
break;
}
case Confirm:
case COnfirmed:
case Deallocate:
case Flush:
case Get_attributes:
case Post_on_receipt:
case Prepare_to_receive:
case Receive_and_wait:
case Receive_immediate:
case Request_to_send:
case Send_data:
case Send_error:
case Test:
{
if (seek_res(s_ptr) == 0)
{
/* ¡á⌐ñÑ¡ ó ß»¿ß¬Ñ */
ps_conv(code, s_ptr);
}
break;
}
default : break;
}
/* Check if verb processing is complete.
* If it's true write response to TP FIFO,
* otherwise place RCB in wait qenue.
*/
sw_retry[ss_ptr - 1] = No;
check_end(code, s_ptr);
if (sw_retry[ss_ptr - 1] == YES) {
sw_retry[ss_ptr - 1] = No;
code = SaveCode[ss_ptr - 1];
s_ptr = SavePtr[ss_ptr - 1];
goto Retry;
}
/* Restore application stack. */
_disable();
if (from_appl[ss_ptr - 1] == YES) {
from_appl[ss_ptr - 1] = No;
_asm
{
mov ax, seg svarea
mov es, ax
mov sp, WORD PTR es:svarea[4]
mov ss, WORD PTR es:svarea[6]
}
}
else
{
_asm
{
mov ax, seg svarea
mov es, ax
mov sp, WORD PTR es:svarea[0]
mov ss, WORD PTR es:svarea[2]
}
}
ss_ptr--;
}
seek_res(s_ptr)
char *s_ptr;
{
struct com *c;
struct tcb *t;
struct rcb *r;
struct repass *p_rep;
#if OS_TYPE == 1
/********* Trace facility **********/
unsigned int rtype; /* type of record */
unsigned int pnum; /* point number */
char pname[8]; /* name of module */
char *drec; /* record for dump */
int lenr; /* record length */
rtype = INPROC;
strcpy(pname, "seek_rs");
pnum = 1;
drec = s_ptr;
lenr = 200;
gtf(rtype, pname, pnum, drec, lenr);
/***********************************/
#endif
/*
* Seek LU_ID and TP_ID for this request
*/
c = (struct com *)s_ptr;
p_rep = (struct repass *)s_ptr;
c -> prim_rc = OK;
c -> sec_rc = 0x00000000;
t = lu6.tcb_list_ptr;
if (t == NULL) {
c -> prim_rc = PARAMETR_CHECK;
c -> sec_rc = 0xf0040000; /* Incomplete */
return(-1);
}
while (t != NULL) {
if (memcmp(c -> tp_id, t -> tcb_id, 8) != 0) {
goto next_tcb;
}
break;
next_tcb:
t = t -> next;
}
if (t == NULL) {
c -> prim_rc = PARAMETR_CHECK;
c -> sec_rc = 0x00000001; /* Bad tp_id */
return(-1);
}
r = t -> rcb_list_ptr;
if (r == NULL) {
c -> prim_rc = PARAMETR_CHECK;
c -> sec_rc = 0xf0040000; /* Incomplete */
return(-1);
}
while (r != NULL) {
if (c -> conv_id != r -> rcb_id) {
goto next_rcb;
}
break;
next_rcb:
r = r -> next;
}
if (r == NULL) {
c -> prim_rc = PARAMETR_CHECK;
c -> sec_rc = BAD_CONV_ID;
return(-1);
}
p_rep -> p_rcb = r;
return (0);
}
lu_init(s_ptr)
char *s_ptr;
{
int j,k;
int t;
unsigned int addr;
unsigned int *ind;
struct attach_lu *a_lu;
struct plu *p_lu;
struct plu_mode *p_mode;
struct pnlu *pr_lu;
struct mode *p_md;
struct pnlu *pr_t; /* Temp pointer */
struct rqb *p_rqb;
char *p;
char *pt;
#if OS_TYPE == 1
/********* Trace facility **********/
unsigned int rtype; /* type of record */
unsigned int pnum; /* point number */
char pname[8]; /* name of module */
char *drec; /* record for dump */
int lenr; /* record length */
rtype = INPROC;
strcpy(pname, "lu_init");
pnum = 1;
drec = s_ptr;
lenr = 200;
gtf(rtype, pname, pnum, drec, lenr);
/***********************************/
#endif
a_lu = (struct attach_lu *)s_ptr;
#if OS_TYPE == 0 /* MS_DOS */
if ((p_rqb = (struct rqb *)calloc(1, sizeof(struct rqb))) == NULL) {
a_lu -> rc = 0xf0030000; /* PORT abended */
return 0;
}
p_rqb -> th.ra.stcb = APPL_CODE;
p_rqb -> th.ra.code = p_rqb -> th.ra.code & 0xbf; /* TOP */
p_rqb -> th.ra.code |= 0x80; /* RQB */
memcpy(p_rqb->th.ra.wa.area, a_lu -> lu_name, 8);
p_rqb -> th.ra.rparm.parm.parm1 = 6; /* Attach */
p = (char *)call_appl(p_rqb);
free( p_rqb );
if (p == NULL) {
a_lu -> rc = INVALID_LU_NAME;
return 0;
}
#endif
a_lu = (struct attach_lu *)s_ptr;
/* Set stack for entry from APPL */
if ((altstack = malloc(2048)) == NULL) {
a_lu -> rc = 0xf0030000; /* PORT abended */
return 0;
}
altsave = altstack; /* save alt. stack address */
_asm
{
mov ax, seg altstack
mov es, ax
mov bx, offset altstack
mov ax, word ptr es:[bx]
add ax, 2048 ; new stack pointer
mov word ptr es:[bx], ax
}
p = (char *)&lu6;
memset(p, 0, sizeof(struct lucb));
psp_ini.lucb_list_ptr = &lu6;
psp_ini.tcb_list_ptr = NULL;
psp_ini.rcb_list_ptr = NULL;
memset(&lu6, 0, sizeof(struct lucb));
a_lu -> rc = 0; /* OK in return code */
tp_exit = a_lu -> tp_exit; /* address for TP exit routine */
/* Initialisation LUCB block */
pt = &((*a_lu).lu_name);
memcpy(lu6.lu_name, pt, 8);
/* Set LU identification */
j = 8 - sizeof(int);
memcpy(lu6.lu_id, name_lu6, j);
addr = getpid();
ind = &(lu6.lu_id[8 - j]);
*ind = addr; /* LU_ID is set */
/* And then return it */
p = &((*a_lu).lu_id);
memcpy(p, lu6.lu_id, 8);
lu6.lu_session_limit = a_lu -> lu_s_limit;
lu6.max_tps = a_lu -> max_tps;
lu6.cur_tps = 0;
lu6.queue_depth = a_lu -> queue_depth;
/* Allocation and initialisation PARTNER_LU block */
k = a_lu -> lt_plu; /* Total length of partner lu records*/
p_lu = (char *)a_lu + sizeof(struct attach_lu);
/* Sizeof struct "attach_lu" */
pr_t = NULL;
while (k > 0) {
t = sizeof(struct plu);
p_mode = (char *)p_lu + t;
/* Allocate memory for partner_lu */
if ((pr_lu = malloc(sizeof(struct pnlu))) == NULL) {
a_lu -> rc = 0xf0030000; /* PORT abended */
return 0;
}
/* Allocate memory for mode block */
if ((p_md = malloc(sizeof(struct mode))) == NULL) {
a_lu -> rc = 0xf0030000; /* PORT abended */
return 0;
}
if (lu6.pluptr == NULL) {
lu6.pluptr = pr_lu;
}
pr_lu -> m_ptr = p_md;
pr_lu -> sess_limit = a_lu -> lu_s_limit;
p = (char *)&((*p_lu).plu_name);
pt = (char *)&((*p_mode).mode_name);
memcpy(pr_lu -> lu_name, p, 8);
memcpy(p_md -> name, pt, 8);
p_md -> session_limit = p_mode -> mmax_neg_slim;
p_md -> ru_h_size = p_mode -> ru_h_size;
p_md -> ru_l_size = p_mode -> ru_l_size;
if (pr_t != NULL) {
pr_t -> next = pr_lu; /* Insert in chain */
}
pr_lu -> next = NULL;
pr_lu -> lu_type = p_lu -> plu_a_num; /* LU type */
p_md -> next = NULL;
pr_t = pr_lu;
j = p_lu -> rec_lt;
k -= j;
p_lu = (char *)p_lu + p_lu -> rec_lt; /* point to next rec. if it exist */
}
lu6.p_acb = &acb_ini;
open_acb(&acb_ini);
return (0);
}
int clt_vb(code, s_ptr)
unsigned int code;
char *s_ptr;
{
struct tp_started *ts;
struct tp_ended *te;
struct tcb *t;
struct tcb *temp;
unsigned long *tpm;
#if OS_TYPE == 1
/********* Trace facility **********/
unsigned int rtype; /* type of record */
unsigned int pnum; /* point number */
char pname[8]; /* name of module */
char *drec; /* record for dump */
int lenr; /* record length */
rtype = INPROC;
strcpy(pname, "clt_vb");
pnum = 1;
drec = s_ptr;
lenr = 200;
gtf(rtype, pname, pnum, drec, lenr);
/***********************************/
#endif
switch (code) {
case TP_STARTED:
{
ts = (struct tp_started *)s_ptr;
ts -> rc = OK;
if (memcmp(ts -> lu_id, lu6.lu_id, 8) != 0) {
/* Bad lu_id */
ts -> rc = 0x00000003;
return 0;
}
if (lu6.cur_tps == lu6.max_tps) {
ts -> rc = 0x00000243; /* too_many_tps*/
return 0;
}
if ((t = calloc(1, sizeof(struct tcb))) == NULL) {
ts -> rc = 0xf0030000; /* PORT abended */
return 0;
}
memset(t, 0, sizeof(struct tcb));
lu6.cur_tps++;
if (lu6.tcb_list_ptr == NULL) {
lu6.tcb_list_ptr = t;
t -> prev = NULL;
}
else
{
temp = lu6.tcb_list_ptr;
while (temp -> next != NULL) {
temp = temp -> next;
}
temp -> next = t;
t -> prev = temp;
}
t -> next = NULL;
memcpy(t -> tcb_id, tpi, 4);
tpm = &((*t).tcb_id[4]);
*tpm = t;
t -> rcb_list_ptr = NULL;
t -> p_lucb = &lu6;
t -> cur_conv = 0;
#if OS_TYPE == 1
p = (char *)s_ptr + sizeof(struct tp_started);
strcpy(t -> tp_name, p);
if (crtp(t) != 0) {
ts -> rc = 0xf0030000; /* PORT abended */
return;
}
#endif
memcpy(ts -> tp_id, t -> tcb_id, 8);
break;
}
case TP_ENDED:
{
te = (struct tp_ended *)s_ptr;
te -> rc = OK;
temp = lu6.tcb_list_ptr;
if (temp == NULL) {
te -> rc = 0xf0040000; /* Incomplete */
return 0;
}
while (temp != NULL) {
if (memcmp(te -> tp_id, temp -> tcb_id, 8) != 0)
goto next_tcb;
break;
next_tcb:
temp = temp -> next;
}
if (temp == NULL) {
te -> rc = 0x00000001; /* Bad tp_id */
return 0;
}
dcp(temp);
#if OS_TYPE == 1
kill(tpst_pid, SIGKILL);
#endif
}
}
}
int lu_sdown(s_ptr)
char *s_ptr;
{
struct scb *p_scb;
struct scb *temp_scb;
struct tcb *p_tcb;
struct mode *p_mode;
struct pnlu *p_pnlu;
struct pnlu *temp_pnlu;
struct rpl *p_rpl;
struct nib *p_nib;
struct detach *d;
#if OS_TYPE == 1
/********* Trace facility **********/
unsigned int rtype; /* type of record */
unsigned int pnum; /* point number */
char pname[8]; /* name of module */
char *drec; /* record for dump */
int lenr; /* record length */
rtype = INPROC;
strcpy(pname, "lu_sdn");
pnum = 1;
drec = s_ptr;
lenr = 200;
gtf(rtype, pname, pnum, drec, lenr);
/***********************************/
#endif
d = (struct detach *)s_ptr;
/*
* Free the TCBs and RCBs.
*/
p_tcb = lu6.tcb_list_ptr;
while (p_tcb != NULL) {
dcp(p_tcb);
p_tcb = p_tcb -> next;
}
/*
* Close the sessions and free SCBs and RPLs, NIBs.
*/
p_scb = lu6.scb_list;
while (p_scb != NULL) {
p_rpl = p_scb -> p_rpl;
clsdst(p_rpl);
p_nib = p_rpl -> p_nib;
if (p_nib != NULL) {
free(p_nib);
}
free(p_rpl);
temp_scb = p_scb;
p_scb = p_scb -> next;
free(temp_scb);
}
/*
* Free MODE block.
*/
if ((p_mode = lu6.p_mode) != NULL) {
free(p_mode);
}
/*
* Free PARTNER_LU blocks
*/
p_pnlu = lu6.pluptr;
while (p_pnlu != NULL) {
temp_pnlu = p_pnlu;
p_pnlu = p_pnlu -> next;
free(temp_pnlu);
}
if (close_acb(&acb_ini) == -1) {
d -> rc = 0xf0030000; /* PORT abended */
}
else
d -> rc = OK;
/*
* Free input buffer for getverb.
*/
if (buff != NULL) {
free(buff);
}
if (altsave != NULL) {
free(altsave);
}
freeMCB();
_disable();
_dos_setvect( 0x68, oldint68 );
_dos_freemem( ProgPrefix ); /* free Program memory */
}
int sessi(codex, s_ptr)
unsigned int codex;
struct segprf *s_ptr; /* pointer to segment */
{
struct scb *p_scb;
struct scb *temp_scb;
struct rpl *p_rpl;
struct rqb *p_rqb;
struct pnlu *pr_lu;
struct rcb *p_rcb;
struct crtp *p_crtp;
struct lucb *p_lucb;
struct tcb *p_tcb;
struct tcb *temp_tcb;
struct mode *p_mode;
char *p;
struct id {
char id_n[4];
unsigned long id_id;
} id_ar;
struct arcb a_rcb;
struct rcballoc rcb_a;
#if OS_TYPE == 1
/********* Trace facility **********/
unsigned int rtype; /* type of record */
unsigned int pnum; /* point number */
char pname[8]; /* name of module */
char *drec; /* record for dump */
int lenr; /* record length */
rtype = INPROC;
strcpy(pname, "sessi");
pnum = 1;
drec = s_ptr;
lenr = 200;
gtf(rtype, pname, pnum, drec, lenr);
/***********************************/
#endif
p_rqb = (char *)s_ptr + 12;
/************ 19.12.92 ***************/
p = (char *)s_ptr + 31;
temp_scb = lu6.scb_list;
while (temp_scb != NULL) {
if (memcmp (temp_scb->lu_name, p, 8) == 0) {
p_rpl = temp_scb->p_rpl;
p_rpl->arg = p_rqb->th.ra.wa.hh.hscb;
return;
}
temp_scb = temp_scb->next;
}
/****************************************/
if ((p_rpl = calloc(1, sizeof(struct rpl))) == NULL) {
return 0;
}
p_rpl -> arg = p_rqb -> th.ra.wa.hh.hscb; /* Save CID in RPL*/
p_rpl -> rsrv3 = 1; /* secondary LU */
if (lu6.cur_sess == lu6.lu_session_limit) {
clsdst(p_rpl);
return 0;
}
lu6.cur_sess++;
if ((p_scb = calloc(1, sizeof(struct scb))) == NULL) {
clsdst(p_rpl);
return 0;
}
/*
* Include SCB in SCB list.
*/
temp_scb = lu6.scb_list;
if (temp_scb == NULL) {
lu6.scb_list = p_scb;
p_scb -> prev = NULL;
}
else
{
while (temp_scb -> next != NULL) {
temp_scb = temp_scb -> next;
}
temp_scb -> next = p_scb;
p_scb -> prev = temp_scb;
}
/*
* Initialisation the SCB
*/
p_scb -> p_rpl = p_rpl;
p_scb -> p_rcb = NULL;
p_scb -> next = NULL;
p_scb -> use = FREE;
/*
* Fill scb.lu_name and scb.mode fields
*/
p = (char *)s_ptr + 31; /* pointer to RU */
memcpy(p_scb -> lu_name, p, 8);
/*
* Try to find this LU name in
* partner LU list.
*/
pr_lu = lu6.pluptr;
while (pr_lu != NULL) {
if (memcmp(pr_lu -> lu_name, p, 8) == 0) {
break;
}
pr_lu = pr_lu -> next;
}
if (pr_lu == NULL) {
/* LU name not found */
clsdst(p_rpl);
return 0;
}
/*
* Check if it's LU type 0 ?
*/
if (pr_lu -> lu_type == 0) {
/* Yes it's LU type 0 ! */
p_rpl -> rsrv3 = 0; /* primary LU */
if ((p_tcb = malloc(sizeof(struct tcb))) == NULL) {
clsdst(p_rpl);
return 0;
}
/* Include TCB in tcb chain */
if (p_lucb -> tcb_list_ptr == NULL) {
p_lucb -> tcb_list_ptr = p_tcb;
}
else
{
temp_tcb = p_lucb -> tcb_list_ptr;
while (temp_tcb -> next != NULL) {
temp_tcb = temp_tcb -> next;
}
temp_tcb -> next = p_tcb;
}
p_tcb -> next = NULL;
p_tcb -> prev = temp_tcb;
p_tcb -> p_lucb = p_lucb;
p_tcb -> cur_conv = 1;
/* Set tcb_id */
memcpy(id_ar.id_n, "TPxx", 4);
id_ar.id_id = p_tcb;
memcpy(p_tcb -> tcb_id, &id_ar, 8);
/* Fill ALLOCATE_RCB record */
memcpy(a_rcb.lu_name, p, 8);
a_rcb.p_tcb = p_tcb;
p_mode = pr_lu -> m_ptr;
memcpy(a_rcb.mode_name, p_mode -> name, 8);
/*
* ALLOCATE_RCB record is complete.
*/
codex = ALLOCATE_RCB;
psrm(codex, &a_rcb, &rcb_a);
if (rcb_a.rc != OK) {
clsdst(p_rpl);
return 0;
}
p_rcb = rcb_a.rcb_ptr;
p_rcb -> sess_corl = p_rqb -> th.ra.wa.hh.hscb; /* Save CID */
p_rcb -> conv_state = SEND; /* Initial state for primary LU */
p_rpl -> arg = p_rqb -> th.ra.wa.hh.hscb; /* Save CID in RPL*/
p_rcb -> p_scb = p_scb;
p_scb -> p_rcb = p_rcb;
p_scb -> use = IN_USE;
p_tcb -> rcb_list_ptr = p_rcb;
/*
* Fill CREATE_TP structure.
*/
if ((p_crtp = calloc(1, sizeof(struct crtp))) == NULL) {
clsdst(p_rpl);
return 0;
}
/*
* Initialisation the CREATE_TP record
*/
p_crtp -> code = 0x0000; /* data_got exit */
p_crtp -> sense = 0;
memcpy(p_crtp -> tp_id, p_tcb -> tcb_id, 8);
memcpy(p_crtp -> lu_id, p_lucb -> lu_id, 8);
p_crtp -> conv_id = p_rcb -> rcb_id;
/*
* Call exit subroutine for LU type 0.
*/
calltpn(p_crtp, p_tcb);
}
}
/*
* Close down a session, free SCB
*/
int sessd(codex, s_ptr)
unsigned int codex;
struct rqb *s_ptr;
{
struct scb *p_scb;
struct scb *temp1_scb;
struct scb *temp2_scb;
struct tcb *p_tcb;
struct rcb *p_rcb;
struct rcb *temp1_rcb;
struct rcb *temp2_rcb;
struct rpl *p_rpl;
struct nib *p_nib;
#if OS_TYPE == 1
/********* Trace facility **********/
unsigned int rtype; /* type of record */
unsigned int pnum; /* point number */
char pname[8]; /* name of module */
char *drec; /* record for dump */
int lenr; /* record length */
rtype = INPROC;
strcpy(pname, "sessd");
pnum = 1;
drec = s_ptr;
lenr = 200;
gtf(rtype, pname, pnum, drec, lenr);
/***********************************/
#endif
/*
* Seek SCB
*/
p_scb = lu6.scb_list;
while (p_scb != NULL) {
if (memcmp(s_ptr -> th.ra.wa.area, p_scb -> lu_name, 8) != 0) {
goto N_scb;
}
break;
N_scb:
p_scb = p_scb -> next;
}
if (p_scb == NULL) {
return 0; /* SCB not found */
}
p_rpl = p_scb -> p_rpl;
p_nib = p_rpl -> p_nib;
if (codex == CLSSESS) {
clsdst(p_rpl);
}
free(p_rpl);
free(p_nib);
if (p_scb -> p_rcb == NULL) {
goto DelScb;
}
p_rcb = p_scb -> p_rcb;
p_tcb = p_rcb -> p_tcb;
/*
* Delete RCB from chain
*/
if (p_rcb -> prev == NULL) {
p_tcb -> rcb_list_ptr = NULL;
goto del_and_exit;
}
temp1_rcb = p_rcb -> prev;
temp2_rcb = p_rcb -> next;
temp1_rcb -> next = temp2_rcb;
if (temp2_rcb != NULL) {
temp2_rcb -> prev = temp1_rcb;
}
del_and_exit:
free(p_rcb);
p_tcb -> cur_conv--;
/*
* Delete SCB from chain
*/
DelScb:
if (p_scb -> prev == NULL) {
lu6.scb_list = NULL;
goto SessdExit;
}
temp1_scb = p_scb -> prev;
temp2_scb = p_scb -> next;
temp1_scb -> next = temp2_scb;
if (temp2_scb != NULL) {
temp2_scb -> prev = temp1_scb;
}
SessdExit:
free(p_scb);
lu6.cur_sess--;
return 0;
}
/*
* Find and post RCB for received data.
*/
fpost(s_ptr)
/*
* In case of "receive_data" sptr points to seg. prefix.
*/
struct segprf *s_ptr;
{
struct scb *p_scb;
struct rcb *p_rcb;
struct rqb *p_rqb;
char *p;
#if OS_TYPE == 1
/********* Trace facility **********/
unsigned int rtype; /* type of record */
unsigned int pnum; /* point number */
char pname[8]; /* name of module */
char *drec; /* record for dump */
int lenr; /* record length */
rtype = INPROC;
strcpy(pname, "fpost");
pnum = 1;
drec = s_ptr;
lenr = 200;
gtf(rtype, pname, pnum, drec, lenr);
/***********************************/
#endif
p = (char *)s_ptr;
p_rqb = (struct rqb *)p;
s_ptr = (char *)p - 12;
p = p_rqb -> th.ra.wa.area; /* OLU name */
p_scb = lu6.scb_list;
if (p_scb == NULL) {
return (-1);
}
while (p_scb != NULL) {
/* next is lines for CID seek.
p_rpl = p_scb -> p_rpl;
if (p_rpl == NULL)
goto Next_Scb;
if (p_rpl -> arg == *cid)
break; */
if (memcmp(p, p_scb -> lu_name, 8) == 0)
break;
/* Next_Scb: */
p_scb = p_scb -> next;
}
if (p_scb == NULL) {
return (-1);
}
p_rcb = p_scb -> p_rcb;
if (p_rcb == NULL) {
return (-1);
}
/* RCB found !!! */
p_rcb -> hsps = YES;
/* This indicator must be reset by RECWAIT func. */
rcvru(p_rcb, s_ptr);
wait_rcb = p_rcb;
#if OS_TYPE == 0
post_rcb(p_rcb); /* post rcb if it found in wait qeue */
#endif
return (0);
}